bitkeeper revision 1.1108.53.1 (410f49091nUueqW95skYILdr1AOlpQ)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 3 Aug 2004 08:12:57 +0000 (08:12 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 3 Aug 2004 08:12:57 +0000 (08:12 +0000)
Fix NMI error code to correctly print a crash dump before hanging.

xen/arch/x86/nmi.c
xen/arch/x86/traps.c
xen/arch/x86/x86_32/entry.S
xen/drivers/char/console.c
xen/drivers/char/serial.c
xen/include/xen/console.h
xen/include/xen/serial.h

index af287444ebbf94e5d3b6cf9547b2257873a2ac66..ec12834ee73d915eac7e2dc057bfd1d1b4c23a46 100644 (file)
@@ -20,6 +20,7 @@
 #include <xen/delay.h>
 #include <xen/time.h>
 #include <xen/sched.h>
+#include <xen/console.h>
 #include <asm/mc146818rtc.h>
 #include <asm/smp.h>
 #include <asm/msr.h>
@@ -271,7 +272,6 @@ void touch_nmi_watchdog (void)
 
 void nmi_watchdog_tick (struct pt_regs * regs)
 {
-    extern spinlock_t console_lock;
     extern void die(const char * str, struct pt_regs * regs, long err);
 
     int sum, cpu = smp_processor_id();
@@ -285,8 +285,9 @@ void nmi_watchdog_tick (struct pt_regs * regs)
          * before doing the oops ...
          */
         alert_counter[cpu]++;
-        if (alert_counter[cpu] == 5*nmi_hz) {
-            console_lock = SPIN_LOCK_UNLOCKED;
+        if ( alert_counter[cpu] == 5*nmi_hz )
+        {
+            console_force_unlock();
             die("NMI Watchdog detected LOCKUP on CPU", regs, cpu);
         }
     } 
index 8de5573d27d32c8c54c85a7129b5209d69c272c3..dbc91d5114b0b9e4b438f5e03b3eb07b9fe5dd0e 100644 (file)
@@ -33,6 +33,7 @@
 #include <xen/lib.h>
 #include <xen/errno.h>
 #include <xen/mm.h>
+#include <xen/console.h>
 #include <asm/ptrace.h>
 #include <xen/delay.h>
 #include <xen/spinlock.h>
@@ -140,7 +141,7 @@ void show_registers(struct pt_regs *regs)
     unsigned long esp;
     unsigned short ss;
 
-    esp = (unsigned long) (&regs->esp);
+    esp = (unsigned long)(&regs->esp);
     ss  = __HYPERVISOR_DS;
     if ( regs->xcs & 3 )
     {
@@ -271,7 +272,6 @@ DO_ERROR_NOCODE( 0, "divide error", divide_error)
 
 asmlinkage void do_double_fault(void)
 {
-    extern spinlock_t console_lock;
     struct tss_struct *tss = &doublefault_tss;
     unsigned int cpu = ((tss->back_link>>3)-__FIRST_TSS_ENTRY)>>1;
 
@@ -295,7 +295,7 @@ asmlinkage void do_double_fault(void)
     printk("************************************\n");
 
     /* Lock up the console to prevent spurious output from other CPUs. */
-    spin_lock(&console_lock); 
+    console_force_lock();
 
     /* Wait for manual reset. */
     for ( ; ; ) ;
@@ -472,9 +472,11 @@ asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
     die("general protection fault", regs, error_code);
 }
 
-asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs *regs)
 {
-    printk("NMI received. Dazed and confused, but trying to continue\n");
+    console_force_unlock();
+
+    printk("\n\nNMI received. Dazed and confused, but trying to continue\n");
     printk("You probably have a hardware problem with your RAM chips\n");
 
     /* Clear and disable the memory parity error line. */
@@ -482,18 +484,40 @@ asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs * regs)
     outb(reason, 0x61);
 
     show_registers(regs);
-    panic("PARITY ERROR");
+
+    printk("************************************\n");
+    printk("CPU%d MEMORY ERROR -- system shutdown\n", smp_processor_id());
+    printk("System needs manual reset.\n");
+    printk("************************************\n");
+
+    /* Lock up the console to prevent spurious output from other CPUs. */
+    console_force_lock();
+
+    /* Wait for manual reset. */
+    for ( ; ; ) ;
 }
 
-asmlinkage void io_check_error(unsigned char reason, struct pt_regs * regs)
+asmlinkage void io_check_error(unsigned char reason, struct pt_regs *regs)
 {
-    printk("NMI: IOCK error (debug interrupt?)\n");
+    console_force_unlock();
+
+    printk("\n\nNMI: IOCK error (debug interrupt?)\n");
 
     reason = (reason & 0xf) | 8;
     outb(reason, 0x61);
 
     show_registers(regs);
-    panic("IOCK ERROR");
+
+    printk("************************************\n");
+    printk("CPU%d I/O ERROR -- system shutdown\n", smp_processor_id());
+    printk("System needs manual reset.\n");
+    printk("************************************\n");
+
+    /* Lock up the console to prevent spurious output from other CPUs. */
+    console_force_lock();
+
+    /* Wait for manual reset. */
+    for ( ; ; ) ;
 }
 
 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
index f3b6885d5a12b69b0aa4af6975b0fd024b113f47..c75c035e4ba7669b4b6c187d649254cf5772552e 100644 (file)
@@ -602,7 +602,7 @@ ENTRY(nmi)
         # reload DS and ES when handling them.
         inb   $0x61,%al
         testb $0x80,%al
-        jne   nmi_parity_err
+        je   nmi_parity_err
         testb $0x40,%al
         jne   nmi_io_err
         movl  %eax,%ebx
@@ -660,14 +660,22 @@ nmi_parity_err:
         movl $(__HYPERVISOR_DS),%edx
         movl %edx,%ds
         movl %edx,%es
-        jmp  SYMBOL_NAME(mem_parity_error)
+        movl %esp,%edx
+        push %edx
+        push %eax
+        call SYMBOL_NAME(mem_parity_error)
+        ud2
         
 nmi_io_err: 
         movl $(__HYPERVISOR_DS),%edx
         movl %edx,%ds
         movl %edx,%es
-        jmp  SYMBOL_NAME(io_check_error)                        
-        
+        movl %esp,%edx
+        push %edx
+        push %eax
+        call SYMBOL_NAME(io_check_error)                        
+        ud2   
+             
 .data
 ENTRY(hypercall_table)
         .long SYMBOL_NAME(do_set_trap_table)     /*  0 */
index 15219b67c77f828a76ef963d9221b639eac16acd..23456261e319ec7ce5682aa8fc06aaa6070e5f25 100644 (file)
@@ -433,6 +433,17 @@ void console_endboot(int disable_vga)
     switch_serial_input();
 }
 
+void console_force_unlock(void)
+{
+    console_lock = SPIN_LOCK_UNLOCKED;
+    serial_force_unlock(sercon_handle);
+}
+
+void console_force_lock(void)
+{
+    spin_lock(&console_lock);
+}
+
 
 /*
  * **************************************************************
index e6ae6c60b9f282f1c320403093b8492446a8f3f5..60e6b02c321782f21845c462cb0bba150f6bc001 100644 (file)
@@ -459,3 +459,10 @@ unsigned char serial_getc(int handle)
     spin_unlock_irqrestore(&uart->lock, flags);
     return c;
 }
+
+void serial_force_unlock(int handle)
+{
+    uart_t *uart = &com[handle & SERHND_IDX];
+    if ( handle != -1 )
+        uart->lock = SPIN_LOCK_UNLOCKED;
+}
index 2a30ef12311118d7aa5b41bba7c9f1fcd1649079..628eb044d45cfaa980e4254f6f3250db8013568f 100644 (file)
@@ -19,4 +19,7 @@ long read_console_ring(unsigned long, unsigned int, unsigned int);
 void init_console(void);
 void console_endboot(int disable_vga);
 
+void console_force_unlock(void);
+void console_force_lock(void);
+
 #endif
index 3640fd036f4f429b0b743ffdc0bd0748365bdebf..6fcc67f228c6a1df1c80b6de3ee03c95561abc07 100644 (file)
@@ -43,4 +43,6 @@ void serial_puts(int handle, const unsigned char *s);
  */
 unsigned char serial_getc(int handle);
 
+void serial_force_unlock(int handle);
+
 #endif /* __XEN_SERIAL_H__ */